# 类和对象的方法到底是怎样的
# 我们一起来探究一下真相
# self绑定给对象方法
# 简单来说就是对象在调用方法的时候会自动把该对象传入
# 该方法的参数一般这个参数我们用self表示
# class A:
#     # 作者@selfmethed省略了
#     # 因为类里面的方法大部分情况下是给实例化后的对象用
#     def f(self,n):
#         print(self,n)
#         print('我是self的方法')
#
# a=A()
# print(a)
# print('==========')
# # 是哪个对象调用的self参数的方法，那么传入的self就是那个对象
# a.f(2)
# # 类调用必须传入对象
# A.f(a,2)

# 绑定给类的方法
# class B:
#     @classmethod
#     def f(cls,n):
#         print(cls,n)
#         print('我是绑定类的方法')
#
# print(B)
# print('========')
# B.f(1)

# b=B()
# 一般不这样用，绑定给类的方法给类用
# b.f()

# 非绑定方法/静态方法
# class C:
#
#     @staticmethod
#     def f(n):
#         print(n)
#         print('我是非绑定方法/静态方法')
# # 纯粹的函数，不会自动传入对象或者类
# C.f(1)
#
# c = C()
#
# # 纯粹的函数，不会自动传入对象或者类
# c.f(2)
# 总结
'''
1、绑定方法（精髓在于自动传值）
特性：绑定给谁就应该由谁来调用，谁来调用就会将谁当作第一个参数自动传入
    绑定方法分为两类:
        1.1 绑定给对象方法
            在类内部定义的函数（没有被任何装饰器修饰的），默认就是绑定给对象用的
        1.2 绑定给类的方法：
            在类内部定义的函数如果被装饰器 @classmethod 装饰，
            那么则是绑定给类的，应该由类来调用，类来调用就自动将类当作第一个参数自动传入
2、非绑定方法（不会自动传值，就是一个 普通函数）
    类中定义的函数如果被装饰器 @staticmethod 装饰，那么该函数就变成非绑定方法
    优点
    既不与类绑定，又不与对象绑定，意味着类与对象都可以来调用
    缺点
    但是无论谁来调用，都没有任何自动传值的效果，就是一个普通函数
3 作用
    如果函数体代码需要用外部传入的类，则应该将该函数定义成绑定给类的方法
    如果函数体代码需要用外部传入的对象，则应该将该函数定义成绑定给对象的方法
    如果函数体代码既不需要外部传入的类也不需要外部传入的对象，则应该将该函数定义成非绑定方法/普通函数
'''

